package com.gap.dam.config;

import io.jsonwebtoken.lang.Assert;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableConfigurationProperties(ElasticSearchProperties.class)
public class ElasticSearchConfig {

    private final ElasticSearchProperties elasticSearchProperties;

    @Autowired
    public ElasticSearchConfig(ElasticSearchProperties elasticSearchProperties) {
        this.elasticSearchProperties = elasticSearchProperties;
    }

    private List<HttpHost> httpHosts = new ArrayList<>();

    @Bean
    @ConditionalOnMissingBean
    public RestHighLevelClient restHighLevelClient() {
        List<String> clusterNodes = elasticSearchProperties.getClusterNodes();
        clusterNodes.forEach(node -> {
            try {
                String[] parts = StringUtils.split(node, ":");
                Assert.notNull(parts, "MUST defined");
                Assert.state(parts.length == 2, "must be defined as 'host:port'");
                httpHosts.add(new HttpHost(parts[0], Integer.parseInt(parts[1]), elasticSearchProperties.getSchema()));
            } catch (Exception ex) {
                throw new IllegalStateException("Invalid es nodes " + node, ex);
            }
        });

        RestClientBuilder builder = RestClient.builder(httpHosts.toArray(new HttpHost[0]));
        return getRestHighLevelClient(builder, elasticSearchProperties);
    }

    private static RestHighLevelClient getRestHighLevelClient(RestClientBuilder builder, ElasticSearchProperties elasticSearchProperties) {
        builder.setRequestConfigCallback(requestConfigBuilder -> {
            requestConfigBuilder.setConnectTimeout(elasticSearchProperties.getConnectionTimeout());
            requestConfigBuilder.setSocketTimeout(elasticSearchProperties.getSocketTimeout());
            requestConfigBuilder.setConnectionRequestTimeout(elasticSearchProperties.getConnectionRequestTimeout());
            return requestConfigBuilder;
        });

        builder.setHttpClientConfigCallback(httpClientConfigBuilder -> {
            httpClientConfigBuilder.setMaxConnTotal(elasticSearchProperties.getMaxConnectionTotal());
            httpClientConfigBuilder.setMaxConnPerRoute(elasticSearchProperties.getMaxConnectionPerRoute());
            return httpClientConfigBuilder;
        });

//        ElasticSearchProperties.Account account = elasticSearchProperties.getAccount();
//        if (!StringUtils.isEmpty(account.getUserName()) && !StringUtils.isEmpty(account.getPassword())) {
//            final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
//            credentialsProvider.setCredentials(AuthScope.ANY,
//                    new UsernamePasswordCredentials(account.getUserName(), account.getPassword()));
//        }

        return new RestHighLevelClient(builder);
    }
}
